package com.demo.ext.user;

import com.demo.common.model.Student;
import com.demo.util.JdbcUtils;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.druid.DruidPlugin;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import static com.demo.common.model.Student.dao;
import java.util.List;

/**
 * @Author: linKe
 * @Date: 2022/4/11 15:45
 * @ClassName: StudentActiveRecordTest
 * @Version: 1.0
 * @Description:
 */
public class StudentActiveRecordTest {
    @Before
    public void before() {
        DruidPlugin dp = JdbcUtils.getDruidPlugin();
        ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
        arp.addMapping("student", Student.class);
        // 与 jfinal web 环境唯一的不同是要手动调用一次相关插件的start()方法
        dp.start();
        arp.start();
    }
    @Test
    public void save(){
        boolean age = new Student().set("num", 22).set("age",32).save();
        Assert.assertTrue(age);
    }
    @Test
    public void findAll(){
        List<Student> all = Student.dao.findAll();
        all.forEach(System.out::println);
    }

    /**
     * <P>1、常用 paginate</P>
     *
     * Model 与 Db 中提供了最常用的分页API：
     * paginate(int pageNumber, int pageSize, String select, String sqlExceptSelect, Object... paras)
     *
     * 其中的参数含义分别为：
     * 当前页的页号、每页数据条数、sql语句的select部分、sql语句除了select以外的部分、查询参数。
     * 绝大多数情况下使用这个API即可
     */
    @Test
    public void findPage(){
        Page<Student> paginate = dao.paginate(1, 10, "select *", "from student where age > ? and num < ?", 18, 50);
        System.out.println(paginate);
    }

    /**
     * <P>2、sql 最外层带 group by 的 paginate</P>
     * paginate(int pageNumber, int pageSize, boolean isGroupBySql, String select, String sqlExceptSelect, Object... paras)，
     * 相对于第一种仅仅多了一个boolean isGroupBySql参数
     * 以上代码中 sql 的最外层有一个 group by age，所以第三个参数 isGroupBySql 要传入 true 值。
     *
     *     如果是嵌套型sql，但是 group by 不在最外层，那么第三个参数必须为 false，例如：select * from (select x from t group by y) as temp。
     *
     *     再次强调：isGroupBy 参数只有在最外层 sql 具有 group by 子句时才能为 true 值，嵌套 sql 中仅仅内层具有 group by 子句时仍然要使用 false。
     *
     */
    @Test
    public void findPageGroup(){
        Page<Student> paginate = dao.paginate(1, 10, true, "select *", "from student where age > ? group by id", 18);
        List<Student> list = paginate.getList();
        list.forEach(System.out::println);

    }

    /**
     * <P>3、paginateByFullSql</P>
     *
     *      API 原型：paginateByFullSql(int pageNumber, int pageSize, String totalRowSql, String findSql, Object... paras)。
     *
     *     相对于其它 paginate API，将查询总行数与查询数据的两条sql独立出来，这样处理主要是应对具有复杂order by语句或者select中带有distinct的情况，只有在使用第一种paginate出现异常时才需要使用该API
     *
     *      上例代码中的order by子句并不复杂，所以仍然可以使用第一种API搞定。
     *
     *     重点：paginateByFullSql 最关键的地方是 totalRowSql、findSql 这两条 sql 要能够共用最后一个参数 Object... paras，相当于 dao.find(totalRowSql, paras) 与 dao.find(findSql, paras) 都要能正确执行，否则断然不能使用 paginateByFullSql。
     *
     *      当 paginate、paginateByFullSql 仍然无法满足业务需求时，可以通过使用 Model.find、Db.query 系列方法组合出自己想要的分页方法。jfinal 只为最常见场景提供支持。
     *
     */
    @Test
    public void findPageByFullSql(){
        String from = "from where where age > ?";
        String totalRowSql = "select count(*) " + from;
        String findSql = "select * " + from + " order by age";
        Page<Student> studentPage = dao.paginateByFullSql(1, 10, totalRowSql, findSql, 18);
        studentPage.getList().forEach(System.out::println);
    }



    @Test
    public void find(){
        // 计算两个数之和
        int sum = dao.find("select sum(num) from student").get(0).getInt("sum(num)");
        System.out.println(sum);
    }

    /**
     * 测试连接
     */
    void  test(){
        // jdbc连接池
        DruidPlugin dp = JdbcUtils.getDruidPlugin();
        // 数据库映射插件
        ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
        // 手动启动插件
        dp.start();
        arp.start();
    }


}
    

